<style lang="css" scoped>

</style>
<template>
  <div class="page-wrap" id="start-page">
    <div id="container"></div>
    <div id="menu">
      <button id="table">TABLE</button>
      <button id="sphere">SPHERE</button>
      <button id="helix">HELIX</button>
      <button id="grid">GRID</button>
    </div>
  </div>
</template>
<script lang="ts">
import { Component } from "vue-property-decorator";
import { mixins } from "vue-class-component";
import PageMixin from "@/common/mixin";
import * as THREE from "three/build/three.module.js";
import TWEEN from "@tweenjs/tween.js";
import TrackballControls from "three-trackballcontrols/index.js";
import { CSS3DRenderer, CSS3DObject } from "three-css3drenderer/index.js";
import { BaiJIaXingTable } from "@/views/mock";
import {sleep} from "@/common/helps";

@Component({
  components: {}
})
export default class Start extends mixins<any>(PageMixin) {

  camera:any = null;
  scene:any = null;
  renderer:any = null;
  controls:any = null;

  objects:any = [];
  targets:any = { table: [], sphere: [], helix: [], grid: [] };

  init() {


    this.camera = new THREE.PerspectiveCamera(
      40,
      window.innerWidth / window.innerHeight,
      1,
      10000
    );
    this.camera.position.z = 3000;

    this.scene = new THREE.Scene();

    // console.log(BaiJIaXingTable.length)


    // table
    for (const key in BaiJIaXingTable) {
      const row = BaiJIaXingTable[key]
      const element = document.createElement("div");
      element.className = "element";
      element.style.backgroundColor =
        "rgba(0,127,127," + (Math.random() * 0.5 + 0.25) + ")";

      const number:any = document.createElement("div");
      number.className = "number";
      number.textContent = key + 1;
      element.appendChild(number);

      const symbol:any = document.createElement("div");
      symbol.className = "symbol";
      symbol.textContent = row[0];
      element.appendChild(symbol);

      const details:any = document.createElement("div");
      details.className = "details";
      details.innerHTML =
          row[1] + "<br>" + row[2];
      element.appendChild(details);

      const objectCSS = new CSS3DObject(element);
      objectCSS.position.x = Math.random() * 4000 - 2000;
      objectCSS.position.y = Math.random() * 4000 - 2000;
      objectCSS.position.z = Math.random() * 4000 - 2000;
      this.scene.add(objectCSS);

      this.objects.push(objectCSS);

      //

      const object = new THREE.Object3D();
      object.position.x = row[3] * 140 - 1330-600;
      object.position.y = -(row[4] * 180) + 990+300;

      this.targets.table.push(object);
    }

    // sphere

    const vector = new THREE.Vector3();

    for (let i = 0, l = this.objects.length; i < l; i++) {
      const phi = Math.acos(-1 + (2 * i) / l);
      const theta = Math.sqrt(l * Math.PI) * phi;

      const object = new THREE.Object3D();

      object.position.setFromSphericalCoords(800, phi, theta);

      vector.copy(object.position).multiplyScalar(2);

      object.lookAt(vector);

      this.targets.sphere.push(object);
    }

    // helix

    for (let i = 0, l = this.objects.length; i < l; i++) {
      const theta = i * 0.175 + Math.PI;
      const y = -(i * 8) + 450;

      const object = new THREE.Object3D();

      object.position.setFromCylindricalCoords(900, theta, y);

      vector.x = object.position.x * 2;
      vector.y = object.position.y;
      vector.z = object.position.z * 2;

      object.lookAt(vector);

      this.targets.helix.push(object);
    }

    // grid

    for (let i = 0; i < this.objects.length; i++) {
      const object = new THREE.Object3D();

      object.position.x = (i % 5) * 400 - 800;
      object.position.y = -(Math.floor(i / 5) % 5) * 400 + 800;
      object.position.z = Math.floor(i / 25) * 1000 - 2000;

      this.targets.grid.push(object);
    }

    //

    this.renderer = new CSS3DRenderer();
    this.renderer.setSize(window.innerWidth, window.innerHeight);
    const wrapEle:any = document.getElementById("container")
    wrapEle.appendChild(this.renderer.domElement);

    //

    this.controls = new TrackballControls(
      this.camera,
      this.renderer.domElement
    );
    this.controls.minDistance = 500;
    this.controls.maxDistance = 6000;
    this.controls.addEventListener("change", this.renderFn);

    const buttonTable:any = document.getElementById("table");
    buttonTable.addEventListener("click", () => {
      this.transform(this.targets.table, 2000);
    });

    const buttonSphere:any = document.getElementById("sphere");
    buttonSphere.addEventListener("click", () => {
      this.transform(this.targets.sphere, 2000);
    });

    const buttonHelix:any = document.getElementById("helix");
    buttonHelix.addEventListener("click", () => {
      this.transform(this.targets.helix, 2000);
    });

    const buttonGrid:any = document.getElementById("grid");
    buttonGrid.addEventListener("click", () => {
      this.transform(this.targets.grid, 2000);
    });

    this.transform(this.targets.table, 2000);

    //

    window.addEventListener("resize", this.onWindowResize);
  }

  transform(targets, duration) {
    TWEEN.removeAll();

    for (let i = 0; i < this.objects.length; i++) {
      const object = this.objects[i];
      const target = targets[i];

      new TWEEN.Tween(object.position)
        .to(
          { x: target.position.x, y: target.position.y, z: target.position.z },
          Math.random() * duration + duration
        )
        .easing(TWEEN.Easing.Exponential.InOut)
        .start();

      new TWEEN.Tween(object.rotation)
        .to(
          { x: target.rotation.x, y: target.rotation.y, z: target.rotation.z },
          Math.random() * duration + duration
        )
        .easing(TWEEN.Easing.Exponential.InOut)
        .start();
    }

    new TWEEN.Tween(this)
      .to({}, duration * 2)
      .onUpdate(this.renderFn)
      .start();
  }

  onWindowResize() {
    this.camera.aspect = window.innerWidth / window.innerHeight;
    this.camera.updateProjectionMatrix();

    this.renderer.setSize(window.innerWidth, window.innerHeight);

    this.renderFn();
  }

  animate() {
    requestAnimationFrame(this.animate);
    TWEEN.update();
    this.controls.update();
  }

  renderFn() {
    this.renderer.render(this.scene, this.camera);
  }

  /**
   * 手动播放欢迎动画
   */
  async showStartFlash(){
    this.transform(this.targets.table, 2000);
    await sleep(5000)
    this.transform(this.targets.table, 2000);
    await sleep(5000)
    this.transform(this.targets.sphere, 2000);
    await sleep(5000)
    this.transform(this.targets.helix, 2000);
    await sleep(5000)
    this.transform(this.targets.grid, 2000);


  }

  created() {

    this.$nextTick().then(()=>{
      console.log(222);
      this.init();
      this.animate();

      this.onWindowResize()

      // sleep(3000,this.showStartFlash)
    })

  }
}
</script>
